package com.jun.common.redis.aspect;

import com.jun.common.redis.aspect.anno.RedisDoubleClear;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Set;

/**
 * @author yuejun.li
 * @date 2024/7/15 21:27
 * 延迟双删切面，未完成
 */
@Aspect
@Component
public class RedisDoubleClearAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 基于注解实现的切入点
     */
    @Pointcut("@annotation(com.jun.common.redis.aspect.anno.RedisDoubleClear)")
    public void pointCut(){

    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return 业务代码的逻辑
     */
    @Around("pointCut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        Signature signature = proceedingJoinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        //获取注解下的方法对象
        Method method = methodSignature.getMethod();
        //反射得到自定义注解对象
        RedisDoubleClear annotation = method.getAnnotation(RedisDoubleClear.class);

        //一维是参数，二维是注解
        //未完成

        //获取自定义注解对象的参数即name
        String name = annotation.name();
        String threadPoolName = annotation.threadPoolName();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = null;
        if(StringUtils.isNotBlank(threadPoolName)){
            threadPoolTaskExecutor = (ThreadPoolTaskExecutor)applicationContext.getBean(threadPoolName);
        }

        if(annotation.isPattern()){
            name = name.concat("*");
        }

        //模糊定义key
        Set<String> keys = redisTemplate.keys(name);
        //模糊删除redis的key值
        redisTemplate.delete(keys);

        //执行加入双删注解的改动数据库的业务 即controller中的方法业务
        Object proceed = null;
        try {
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        String finalName = name;
        Runnable runnable = () -> {
            try {
                Thread.sleep(1000);
                //模糊删除
                Set<String> keys1 = redisTemplate.keys(finalName);
                redisTemplate.delete(keys1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        };
        threadPoolTaskExecutor.execute(runnable);
        return proceed;
    }
}
